package com.canxi.user.wx;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.canxi.common.core.controller.BaseController;
import com.canxi.common.core.domain.R;
import com.canxi.common.enums.DeviceType;
import com.canxi.common.exception.ServiceException;
import com.canxi.user.domain.bo.CxUserBo;
import com.canxi.user.domain.vo.CxUserVo;
import com.canxi.user.service.IUserService;
import com.canxi.user.utils.CXLoginUtils;
import com.canxi.user.vo.LoginVo;
import com.canxi.cxcommon.enums.CXUserType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;


@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/core/wx")
public class WxLoginController extends BaseController {

    @Resource
    private final WxMaService wxMaService;

    @Resource
    private IUserService iUserService;

    /**
     * 登陆接口
     */

    @SaIgnore
    @GetMapping("/login")
    public R<LoginVo> login(String appid, String code) {

        if (StringUtils.isBlank(code) || StringUtils.isBlank(appid)) {
            throw  new ServiceException("参数不全");
        }

        if (!wxMaService.switchover(appid)) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        }


        //通过缓存判断用户信息

        CxUserVo userVo = CXLoginUtils.getUserByToken();
        if (ObjectUtil.isNotNull(userVo)){
            CXLoginUtils.refreshUser(userVo,false, DeviceType.XCX, CXUserType.xcx.getCode());

            return CXLoginUtils.authMsg(userVo);
        }

        WxMaJscode2SessionResult session = getSession(appid,code);
        String openid = session.getOpenid();


        userVo =  iUserService.getByOpenid(openid);
        if (ObjectUtil.isNull(userVo)){
            CxUserBo userBo = new CxUserBo();
            userBo.setOpenid(openid);
            userBo.setUtype("小程序");//小程序
            iUserService.insertByBo(userBo);


            CXLoginUtils.refreshUser(BeanUtil.toBean(userBo,CxUserVo.class),true,DeviceType.XCX, CXUserType.xcx.getCode());

            return R.fail("首次未授权",new LoginVo(StpUtil.getTokenValue(),BeanUtil.toBean(userBo,CxUserVo.class),"1"));

        }
        CXLoginUtils.refreshUser(userVo,true,DeviceType.XCX, CXUserType.xcx.getCode());


        return CXLoginUtils.authMsg(userVo);
    }

    private WxMaJscode2SessionResult getSession(String appid, String code) {
        String openid = "";
        try {
            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);


            return session;


        } catch (WxErrorException e) {
            log.error(e.getMessage(), e);
            throw new ServiceException("微信接口异常");
        } finally {
            WxMaConfigHolder.remove();//清理ThreadLocal
        }
    }

    /***
     * 授权登录
     * @param UserBo 用户对象
     * @return
     */
    @PostMapping("auth")
    public R<Void> auth(@RequestBody CxUserBo bo){
        if (StringUtils.isBlank(bo.getNickname()) || StringUtils.isBlank(bo.getAvatar())){
            return R.fail("参数不全");
        }
        try {
            Long userId = getUserId();
            CxUserVo userVo = iUserService.queryById(String.valueOf(userId));
            if (ObjectUtil.isNull(userVo)){
                return R.fail("授权有误");
            }
            CxUserBo userBo = BeanUtil.toBean(userVo, CxUserBo.class);
            userBo.setNickname(bo.getNickname());
            userBo.setAvatar(bo.getAvatar());
            iUserService.updateByBo(userBo);
            CXLoginUtils.refreshUser(userVo,false,DeviceType.XCX, CXUserType.xcx.getCode());


            return R.ok("授权成功");

        }catch (Exception e){
            return R.fail("授权有误");
        }


    }

    @SaIgnore
    @GetMapping("test")
    public  R<Void> test(){
        return R.ok("请求成功");

    }


}
